﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Markup;

namespace Labthink.PCSoft.UniversalHost4.Utility
{
    public class LanguageManager
    {
        private static string _currentLanguage = "zh-CN";

        public static string CurrentLanguage
        {
            get => _currentLanguage;
            set
            {
                if (UpdateCurrentLanguage(value))
                    _currentLanguage = value;
            }
        }

        /// <summary>
        /// 所有语言
        /// </summary>
        public static List<Language> Languages { get; } = new List<Language>();

        /// <summary>
        /// 初始化, 加载语言目录下的所有语言文件
        /// </summary>
        public static void Initialize()
        {
            AddLanguages("Languages");
        }

        public static void AddLanguages(string directoryName)
        {
            string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, directoryName);
            if (!Directory.Exists(dir)) return;

            var directory = new DirectoryInfo(dir);
            FileInfo[] files = directory.GetFiles();
            foreach (FileInfo item in files)
            {
                var language = new Language();
                var rd = new ResourceDictionary
                {
                    Source = new Uri(item.FullName)
                };

                language.Code = rd["Code"] == null ? "未知" : rd["Code"].ToString();
                language.Name = rd["Name"] == null ? "未知" : rd["Name"].ToString();
                language.DisplayName = rd["DisplayName"] == null ? "未知" : rd["DisplayName"].ToString();
                language.Enabled = rd["Enabled"] != null && bool.Parse(rd["Enabled"].ToString());
                language.Resourcefile = item.FullName;
                language.Resource = rd;

                if (language.Enabled)
                {
                    Languages.Add(language);
                }
            }
        }

        /// <summary>
        /// 更新语言配置,同时同步CurrentLanguage字段
        /// </summary>
        private static bool UpdateCurrentLanguage(string languageCode)
        {
            if (Languages.Exists(p => p.Code == languageCode && p.Enabled == true))
            {
                var languages = Languages.FindAll(p => p.Code == languageCode && p.Enabled == true);
                foreach (Language item in Languages)
                {
                    Application.Current.Resources.MergedDictionaries.Remove(item.Resource);
                }

                foreach (Language lan in languages)
                {
                    Application.Current.Resources.MergedDictionaries.Add(lan.Resource);
                }

                // 同时更新线程的Culture
                var culture = CultureInfo.CreateSpecificCulture(languageCode);
                Thread.CurrentThread.CurrentCulture = culture;
                Thread.CurrentThread.CurrentUICulture = culture;
                XmlLanguage lang = XmlLanguage.GetLanguage(culture.IetfLanguageTag);
                FrameworkElement.LanguageProperty.OverrideMetadata(
                    typeof(FrameworkElement),
                    new FrameworkPropertyMetadata(lang)
                );

                FrameworkContentElement.LanguageProperty.OverrideMetadata(
                    typeof(System.Windows.Documents.TextElement),
                    new FrameworkPropertyMetadata(lang)
                );

                return true;
            }

            return false;
        }

        /// <summary>
        /// 查找语言资源文件具体的某项值,类似索引器
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetLanguageValue(string key)
        {
            ResourceDictionary rd = Application.Current.Resources;
            object obj = rd[key];
            return obj?.ToString() ?? key;
        }

        public static string GetLanguageValue(string key, params object[] args)
        {
            var r = GetLanguageValue(key);
            if (args != null && args.Length > 0)
            {
                return string.Format(r, args);
            }

            return r;
        }
    }
}
